package com.grant.HelloWorld.server;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.util.Date;

import javax.jdo.PersistenceManager;
import javax.jdo.annotations.IdGeneratorStrategy;
import javax.jdo.annotations.IdentityType;
import javax.jdo.annotations.NotPersistent;
import javax.jdo.annotations.PersistenceCapable;
import javax.jdo.annotations.Persistent;
import javax.jdo.annotations.PrimaryKey;

import org.apache.commons.fileupload.FileItem;

import com.google.appengine.api.datastore.Blob;


@PersistenceCapable(identityType = IdentityType.APPLICATION)
public class MemoryFileItem implements FileItem {

  /**
   * 
   */
  private static final long serialVersionUID = 6873943621309250882L;
  
    @PrimaryKey
    @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
    protected Long id;
    
    @NotPersistent
  private String fieldName;
    
    @Persistent
    protected String contentType;
    
    @Persistent
    protected String fileName;
    
    @NotPersistent
  private boolean isFormField;
  
    @NotPersistent
  private ByteArrayOutputStream content_out;
    
    @Persistent
    protected Blob content;
    
    @Persistent
    protected Date date_created;
  
  public MemoryFileItem(String fieldName, String contentType, boolean isFormField,
      String fileName, int maxSize){
    this.fieldName = fieldName;
    this.contentType = contentType;
    this.isFormField = isFormField;
    this.fileName = fileName;
    this.content = null;
    this.content_out = (maxSize > 0) ?  new ByteArrayOutputStream(maxSize) : new ByteArrayOutputStream();
    this.date_created = new Date();
  }
  
  public Long getId() {
    return id;
  }

  public void delete() {
    //Unimplemented - memory only, no cleaning up needed.
  }

  public byte[] get() {
    return (content != null)?  content.getBytes() : content_out.toByteArray(); 
  }

  public String getContentType() {
    return contentType;
  }

  public String getFieldName() {
    return fieldName;
  }

  public InputStream getInputStream() throws IOException {
    ByteArrayInputStream bais;
    if(content != null){
      bais = new ByteArrayInputStream(content.getBytes());
    } else {
      bais = new ByteArrayInputStream(content_out.toByteArray());
    }
    return bais;
  }

  public String getName() {
    return fileName;
  }

  /**
   * This method can't be used if object was fetched from datastore.
   * */
  public OutputStream getOutputStream() throws IOException {
    return content_out;
  }

  public long getSize() {
    return (content != null) ? content.getBytes().length : content_out.size();
  }

  public String getString() {
    return (content != null) ? new String(content.getBytes()) : new String(content_out.toByteArray());
  }

  public String getString(String arg0) throws UnsupportedEncodingException {
    return (content != null) ? new String(content.getBytes(), arg0) : new String(content_out.toByteArray(), arg0);
  }

  public boolean isFormField() {
    return isFormField;
  }

  public boolean isInMemory() {
    return true;
  }

  public void setFieldName(String arg0) {
    this.fieldName = arg0;
  }

  public void setFormField(boolean arg0) {
    this.isFormField = arg0;
  }

  public void write(File arg0) throws Exception {
    // Unimplemented - can't use FileWriter in GAE.
  }

  public boolean commit(){
    
    content = new Blob(get());
    
    PersistenceManager pm = PMF.get().getPersistenceManager();
    
    MemoryFileItem obj = null;
    try{
      obj = pm.makePersistent(this);
    } finally {
      pm.close();
    }
    return obj != null;
  }

  public Date getDate() {
    return date_created;
  }
  
}

